package co.edu.unal.franquicias.visa.util;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import co.edu.unal.franquicias.visa.exceptions.ServiceLocatorException;

public class ServiceLocator {

	private static Map<String, Object> cache;
	private InitialContext ic;

	private static ServiceLocator instance;

	static {
		try {
			instance = new ServiceLocator();
		} catch (ServiceLocatorException se) {
			System.err.println(se);
			se.printStackTrace(System.err);
		}
	}

	protected ServiceLocator() {
		try {

			Properties props = new Properties();
			props.put(Context.INITIAL_CONTEXT_FACTORY,
					"com.sun.enterprise.naming.SerialInitContextFactory");
			props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
			props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

			ic = new InitialContext(props);
			cache = Collections.synchronizedMap(new HashMap<String, Object>());
		} catch (NamingException e) {
			throw new ServiceLocatorException(e);
		}
	}

	public Object getResource(String name) throws ServiceLocatorException {

		if (cache.containsKey(name)) {
			return cache.get(name);
		}

		try {
			Object object = ic.lookup(name);
			cache.put(name, object);
			return object;
		} catch (NamingException e) {
			throw new ServiceLocatorException();
		}
	}

	/**
	 * Obtiene la instancia singleton del ServiceLocator
	 * 
	 * @return la instancia singleton del ServiceLocator
	 * @throws RemoteServiceLocatorException
	 *             si el contexto no pudo ser inicializado
	 */
	public static ServiceLocator getInstance() {
		return instance;
	}
}